package com.redxun.core.api.impl;

import com.alibaba.druid.filter.config.ConfigTools;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.redxun.core.api.form.IDataSourceHandler;
import com.redxun.core.common.constant.MBoolean;
import com.redxun.core.common.entity.JsonResult;
import com.redxun.core.common.utils.ExceptionUtil;
import com.redxun.core.common.utils.SpringUtil;
import com.redxun.core.db.datasource.DynamicDataSourceRegister;
import com.redxun.core.db.listener.DataSourceUpdEvent;
import com.redxun.core.db.util.DataSourceUtil;
import com.redxun.core.dto.form.FormDataSourceDefDto;
import com.redxun.core.tool.BeanUtil;
import com.redxun.form.core.service.FormDataSourceDefServiceImpl;
import javax.sql.DataSource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 功能: 单体版数据源处理。
 * @author ray
 * @date 2024/1/21 22:14
 */
@Component
@Slf4j
public class BootDataSourceHandler implements IDataSourceHandler {
    @Autowired
    DynamicDataSourceRegister  dynamicDataSourceRegister;
    @Autowired
    FormDataSourceDefServiceImpl   formDataSourceDefService;
    
    @Override
    public void publishDataSource(FormDataSourceDefDto formDataSourceDef) {
        try {
            String alias=formDataSourceDef.getAlias();
            //关闭同名的数据源。
            dynamicDataSourceRegister.removeDatasourceClose(alias);
            
            if(!MBoolean.TRUE_LOWER.val.equals( formDataSourceDef.getEnable())){
                return;
            }
            //新建数据源。
            DataSource dataSource =  DataSourceUtil.buildDataSource(alias, formDataSourceDef.getSetting());
            DataSource dsProxy= dynamicDataSourceRegister.registerDataSource(alias,dataSource);
            DataSourceUtil.addDataSource(alias, dsProxy, true);
            //发布事件。
            DataSourceUpdEvent updEvent=new DataSourceUpdEvent(alias);
            SpringUtil.publishEvent(updEvent);
        } catch (Exception e) {
            log.error(ExceptionUtil.getExceptionMessage(e));
        }
    }
    
    @Override
    public void loadDataSource() {
        JSONObject dataSourceConfig = formDataSourceDefService.getEnableJsonList();
        if(BeanUtil.isEmpty(dataSourceConfig)){
            return;
        }
        
        // 添加数据实例到容器中
        for (String key : dataSourceConfig.keySet()) {
            try {
                JSONObject json = dataSourceConfig.getJSONObject(key);
                
                DataSource dataSource = DataSourceUtil.buildDataSource(key, json.getString("setting"));
                if (dataSource  !=  null) {
                    //数据源进行代理.
                    DataSource dsProxy = (DataSource) dynamicDataSourceRegister.registerDataSource(key, dataSource);
                    DataSourceUtil.addDataSource(key, dsProxy, true);
                }
                
            } catch (Exception e) {
                //错误信息
                log.error(ExceptionUtil.getExceptionMessage(e));
            }
        }
    }
    
    @Override
    public JsonResult validateDataSource(FormDataSourceDefDto formDataSourceDef, boolean onlyTestDb) {
        String dbType = formDataSourceDef.getDbType();
        String json = formDataSourceDef.getSetting();
        JSONArray jsonArray = JSONArray.parseArray(json);
        String url  = getValByName(jsonArray, "url");
        
        String username = getValByName(jsonArray, "username");
        String password = getValByName(jsonArray, "password");
        boolean encrypt =  MBoolean.TRUE_LOWER.val.equals(formDataSourceDef.getEncrypt());
        if (encrypt) {
            try {
                password  =  ConfigTools.decrypt(password);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        JsonResult result =  DataSourceUtil.validConn(dbType, url, username, password);
        return result;
    }
    
    @Override
    public void unloadDataSource(FormDataSourceDefDto formDataSourceDef) {
        try{
            String alias=formDataSourceDef.getAlias();
            //关闭同名的数据源。
            dynamicDataSourceRegister.removeDatasourceClose(alias);
        }
        catch (Exception e){
            log.error(ExceptionUtil.getExceptionMessage(e));
        }
        
    }
    
    
    /**
     * 根据名字获取值。
     * @param jsonArray
     * @param inName
     * @return
     */
    private String getValByName(JSONArray jsonArray, String inName) {
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject obj = jsonArray.getJSONObject(i);
            String name = obj.getString("name");
            if (inName.equals(name)) {
                return obj.getString("val");
            }
        }
        return "";
    }
    
    
}
